


using System.Xml.Serialization;
using System.Collections;
using System;
using umbraco.BusinessLogic.Utils;
using System.Xml.Schema;
using umbraco.interfaces;
using System.Collections.Generic;
namespace umbraco.cms.presentation.Trees
{

	public struct Declarations
	{
		public const string SchemaVersion = "";
	}

    /// <summary>
    /// Used for serializing data to XML as the data structure for the JavaScript tree
    /// </summary>
	[XmlRoot(ElementName="tree",IsNullable=false),Serializable]
	public class XmlTree
	{
        /// <summary>
        /// Returns the string representation of the XML structure
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return SerializableData.Serialize(this, typeof(XmlTree));
        }

		[System.Runtime.InteropServices.DispIdAttribute(-4)]
		public IEnumerator GetEnumerator() 
		{
            return treeCollection.GetEnumerator();
		}

        public void Add(XmlTreeNode obj)
		{
			treeCollection.Add(obj);
		}

		[XmlIgnore]
        public XmlTreeNode this[int index]
		{
            get { return (XmlTreeNode)treeCollection[index]; }
		}

		[XmlIgnore]
        public int Count 
		{
            get { return treeCollection.Count; }
        }

        public void Clear()
		{
			treeCollection.Clear();
        }

        public XmlTreeNode Remove(int index) 
		{
            XmlTreeNode obj = treeCollection[index];
            treeCollection.Remove(obj);
			return obj;
        }

        public void Remove(XmlTreeNode obj)
		{
            treeCollection.Remove(obj);
        }

		
        private List<XmlTreeNode> __treeCollection;

        [XmlElement(Type = typeof(XmlTreeNode), ElementName = "tree", IsNullable = false, Form = XmlSchemaForm.Qualified)]
        public List<XmlTreeNode> treeCollection
		{
			get
			{
                if (__treeCollection == null) __treeCollection = new List<XmlTreeNode>();
				return __treeCollection;
			}
			set {__treeCollection = value;}
		}

		public XmlTree()
		{
		}
	}

    /// <summary>
    /// Used for serializing data to XML as the data structure for the JavaScript tree
    /// </summary>
	//[XmlType(TypeName="tree"),Serializable]
    [Serializable]
	public class XmlTreeNode : IXmlSerializable
	{

        private XmlTreeNode() { }

        /// <summary>
        /// creates a new XmlTreeNode with the default parameters from the BaseTree
        /// </summary>
        /// <param name="bTree"></param>
        /// <returns></returns>
        public static XmlTreeNode Create(BaseTree bTree)
        {
            XmlTreeNode xNode = new XmlTreeNode();
            xNode.Menu = bTree.AllowedActions.FindAll(delegate(IAction a) { return true; }); //return a duplicate copy of the list
            xNode.NodeType = bTree.TreeAlias;
            xNode.Source = string.Empty;
            return xNode;
        }

        /// <summary>
        /// creates a new XmlTreeNode with the default parameters for the BaseTree root node
        /// </summary>
        /// <param name="bTree"></param>
        /// <returns></returns>
        public static XmlTreeNode CreateRoot(BaseTree bTree)
        {
            XmlTreeNode xNode = new XmlTreeNode();
            xNode.NodeID = bTree.StartNodeID.ToString();
            xNode.Source = bTree.GetTreeServiceUrl();
            xNode.Menu = bTree.RootNodeActions.FindAll(delegate(IAction a) { return true; }); //return a duplicate copy of the list
            xNode.NodeType = bTree.TreeAlias;
            xNode.Text = BaseTree.GetTreeHeader(bTree.TreeAlias);
            //by default, all root nodes will open the dashboard to their application
            xNode.Action = string.Format("javascript:parent.openDashboard('{0}');", bTree.app);
            return xNode;
        }

        /// <summary>
        /// Dims the node by setting the css class the umbraco-tree-icon-grey.
        /// </summary>
        public void DimNode() { 
            this.IconClass = "umbraco-tree-icon-grey";
        }

        private bool? m_notPublished;
        private bool? m_isProtected;
        private List<IAction> m_menu;
		private string m_text;
		private string m_action;
		private string m_rootSrc;
        private string m_src;
		private string m_iconClass;
        private string m_icon;
		private string m_openIcon;
		private string m_nodeType;
		private string m_nodeID;

        public string NodeID
        {
            get { return m_nodeID; }
            set { m_nodeID = value; }
        }

        /// <summary>
        /// The tree node text
        /// </summary>
        public string Text
        {
            get { return m_text; }
            set { m_text = value; }
        }

        /// <summary>
        /// The CSS class of the icon to use for the node
        /// </summary>
        public string IconClass
        {
            get { return m_iconClass; }
            set { m_iconClass = value; }
        }

        /// <summary>
        /// The JavaScript action for the node
        /// </summary>
        public string Action
        {
            get { return m_action; }
            set { m_action = value; }
        }

        /// <summary>
        /// A string of letters representing actions for the context menu
        /// </summary>
        public List<IAction> Menu
        {
            get { return m_menu; }
            set { m_menu = value; }
        }

        /// <summary>
        /// The xml source for the child nodes (a URL)
        /// </summary>      
        public string Source
        {
            get { return m_src; }
            set { m_src = value; }
        }

        /// <summary>
        /// The path to the icon to display for the node
        /// </summary>
        public string Icon
        {
            get { return m_icon; }
            set { m_icon = value; }
        }

        /// <summary>
        /// The path to the icon to display for the node if the node is showing it's children
        /// </summary>
        public string OpenIcon
        {
            get { return m_openIcon; }
            set { m_openIcon = value; }
        }

        /// <summary>
        /// Normally just the type of tree being rendered
        /// </summary>
        public string NodeType
        {
            get { return m_nodeType; }
            set { m_nodeType = value; }
        }

        /// <summary>
        /// Used by the content tree and flagged as true if the node is not published
        /// </summary>
        public bool? NotPublished
        {
            get { return m_notPublished; }
            set { m_notPublished = value; }
        }

        /// <summary>
        /// Used by the content tree and flagged as true if the node is protected
        /// </summary>
        public bool? IsProtected
        {
            get { return m_isProtected; }
            set { m_isProtected = value; }
        }


        #region IXmlSerializable Members

        public XmlSchema GetSchema()
        {
            return null;
        }

        public void ReadXml(System.Xml.XmlReader reader)
        {
            if (reader.HasAttributes)
            {
                while (reader.MoveToNextAttribute())
                {
                    //try to parse the name into enum
                    TreeAttributes current;
                    try
                    {
                        current = (TreeAttributes)Enum.Parse(typeof(TreeAttributes), reader.Name, true);
                    }
                    catch
                    {
                        break;
                    }
                    switch (current)
                    {
                        case TreeAttributes.nodeID:
                            this.m_nodeID = reader.Value;
                            break;
                        case TreeAttributes.text:
                            this.m_text = reader.Value;
                            break;
                        case TreeAttributes.iconClass:
                            this.m_iconClass = reader.Value;
                            break;
                        case TreeAttributes.action:
                            this.m_action = reader.Value;
                            break;
                        case TreeAttributes.menu:
                            this.m_menu = (!string.IsNullOrEmpty(reader.Value) ? umbraco.BusinessLogic.Actions.Action.FromString(reader.Value) : null);
                            break;
                        case TreeAttributes.rootSrc:
                            this.m_rootSrc = reader.Value;
                            break;
                        case TreeAttributes.src:
                            this.m_src = reader.Value;
                            break;
                        case TreeAttributes.icon:
                            this.m_icon = reader.Value;
                            break;
                        case TreeAttributes.openIcon:
                            this.m_openIcon = reader.Value;
                            break;
                        case TreeAttributes.nodeType:
                            this.m_nodeType = reader.Value;
                            break;
                        case TreeAttributes.notPublished:
                            if (!string.IsNullOrEmpty(reader.Value)) this.m_notPublished = bool.Parse(reader.Value);
                            break;
                        case TreeAttributes.isProtected:
                            if (!string.IsNullOrEmpty(reader.Value)) this.m_isProtected = bool.Parse(reader.Value);
                            break;

                    }
                }
            }

            reader.Read();
        }

        public void WriteXml(System.Xml.XmlWriter writer)
        {
            writer.WriteAttributeString(TreeAttributes.nodeID.ToString(), this.m_nodeID);
            writer.WriteAttributeString(TreeAttributes.text.ToString(), this.m_text);
            writer.WriteAttributeString(TreeAttributes.iconClass.ToString(), this.m_iconClass);
            writer.WriteAttributeString(TreeAttributes.action.ToString(), this.m_action);
            writer.WriteAttributeString(TreeAttributes.menu.ToString(), (this.m_menu != null && this.m_menu.Count > 0 ? umbraco.BusinessLogic.Actions.Action.ToString(this.m_menu) : ""));
            writer.WriteAttributeString(TreeAttributes.rootSrc.ToString(), this.m_rootSrc);
            writer.WriteAttributeString(TreeAttributes.src.ToString(), this.m_src);
            writer.WriteAttributeString(TreeAttributes.icon.ToString(), this.m_icon);
            writer.WriteAttributeString(TreeAttributes.openIcon.ToString(), this.m_openIcon);
            writer.WriteAttributeString(TreeAttributes.nodeType.ToString(), this.m_nodeType);
            if (m_notPublished.HasValue) writer.WriteAttributeString(TreeAttributes.notPublished.ToString(), this.m_notPublished.Value.ToString().ToLower());
            if (m_isProtected.HasValue) writer.WriteAttributeString(TreeAttributes.isProtected.ToString(), this.m_isProtected.Value.ToString().ToLower());
        }

        private enum TreeAttributes
        {
            nodeID, text, iconClass, action, menu, rootSrc, src, icon, openIcon, nodeType, notPublished, isProtected
        }

        #endregion
       
    }
}
